﻿using BlackList.Forms;
using BlackList.YiYeSync;
using CefSharp;
using CefSharp.WinForms;
using QWManage.API.AccessToken;
using QWManage.API.BlockedUsersCustom;
using QWManage.API.CustomerDetailB92994;
using QWManage.API.DepartmentDetail95351;
using QWManage.API.DepartmentList95350;
using QWManage.API.ExternalUserids92113;
using QWManage.API.GroupChatDetail92122;
using QWManage.API.GroupChatList92120;
using QWManage.API.Users96067;
using QWManage.DAL;
using QWManage.Forms;
using QWManage.Logs;
using QWManage.Model;
using QWManage.MySqlSync;
using QWManage.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace QWManage
{
    public partial class FrmMain : Form
    {
        private ChromiumWebBrowser _chromeBrowser;
        private Thread _thread = null;
        private Thread _groupsThread = null;
        private Thread _dailyThread = null;

        public FrmMain()
        {
            InitializeComponent();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            AppConfigInfo appConfigInfo = AppCofingMgr.Get();
            if (!string.IsNullOrEmpty(appConfigInfo.CorpName))
                this.Text = appConfigInfo.CorpName + "---用户信息管理";
            else
                this.Text = "用户信息管理";

            tlblStatus.Text = "";
            lblStatus.Text = "";
            string defaultUrl = "";

            string homepage_fn = Path.Combine(Application.StartupPath, "HomePage.html");
            if (File.Exists(homepage_fn))
                defaultUrl = homepage_fn;

            this.FormClosing += FrmMain_FormClosing;
            CefSettings settings = new CefSettings();
            // settings.Locale = "zh-CN";
            //settings.Locale = "zh"
            settings.AcceptLanguageList = "zh-CN";
            // Initialize cef with the provided settings
            settings.CachePath = Path.Combine(Application.StartupPath, "cache");
            settings.PersistUserPreferences = true;
            settings.LogSeverity = LogSeverity.Disable;//于CefSharp的这一块日志是默认开启的，取消掉
            Cef.Initialize(settings);
            // Create a browser component
            _chromeBrowser = new ChromiumWebBrowser(defaultUrl);
            // Add it to the form and fill it to the form window.
            panelMain.Controls.Add(_chromeBrowser);

            LifeSpanHandler lifeSpanHandler = new LifeSpanHandler();
            _chromeBrowser.LifeSpanHandler = lifeSpanHandler;
            lifeSpanHandler.PopupRequest += LifeSpanHander_PopupRequest;

            _chromeBrowser.Dock = DockStyle.Fill;
            _groupsThread = new Thread(new ThreadStart(TimerTask.GroupsThread.Run));
            _groupsThread.Start();

            _dailyThread = new Thread(new ThreadStart(dailyService));
            _dailyThread.Start();
        }

        private void dailyService()
        {
            try
            {
                LogMgr.Log("定时采集", "线程开始 OK");
                while (true)
                {
                    AppConfigInfo appConfig = AppCofingMgr.Get();
                    if (!appConfig.Daily)
                    {
                        Thread.Sleep(1000 * 10); //每十秒钟查一次
                        continue;
                    }
                    if (appConfig.Hour == DateTime.Now.Hour && appConfig.Minute == DateTime.Now.Minute)
                    {
                        LogMgr.Log("定时采集", "定时时间 准备膝中 OK");
                        Thread.Sleep(2 * 1000 * 60); //先停2分多钟这样，以避免重复条件相等
                        LogMgr.Log("定时采集", "开始采集 OK");
                        workService(new object());//开搞
                        LogMgr.Log("定时采集", "开始结束 OK");
                    }
                }
            }
            catch (ThreadAbortException ex)
            {
                LogMgr.Log(ex);
                LogMgr.Log("定时采集", "ThreadAbortException", LogLevel.Error);
            }
            catch (Exception ex)
            {
                LogMgr.Log(ex);
                LogMgr.Log("定时采集报错", ex.Message, LogLevel.Error);
            }
            finally
            {
                LogMgr.Log("定时采集", "线程退出 OK");
            }
        }

        private void LifeSpanHander_PopupRequest(string obj)
        {
            _chromeBrowser.Load(obj);
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_thread != null && _thread.IsAlive) _thread.Abort();
            if (_groupsThread != null && _groupsThread.IsAlive) _groupsThread.Abort();
            if (_dailyThread != null && _dailyThread.IsAlive) _dailyThread.Abort();
            Cef.Shutdown();
        }

        private string getHtmlSource()
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                Task<string> taskHtml = CefSharp.WebBrowserExtensions.GetSourceAsync(_chromeBrowser);

                var frameIdent = _chromeBrowser.GetBrowser().GetFrameIdentifiers();
                foreach (long ident in frameIdent)
                {
                    var result = _chromeBrowser.GetBrowser().GetFrame(ident).GetSourceAsync().Result;
                    sb.AppendLine(result.ToString());
                }
                string htmlSource = sb.ToString();
                return htmlSource;
            }
            catch { return ""; }
        }

        private void workService(object obj = null)
        {
            try
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        foreach (var toolStripItem in toolStrip.Items)
                        {
                            ToolStripButton btn = toolStripItem as ToolStripButton;
                            if (btn != null) btn.Enabled = false;
                        }
                    }));
                }
                LogMgr.Log("用户数据采集", "获取Tokens");

                string tokenA = TokenA.GetAccessToken(true);
                string tokenB = TokenB.GetAccessToken(true);

                LogMgr.Log("用户数据采集", "1、采集部门 开始");
                //1、采集部门
                List<int> department_ids = DepartmentListAPI.Invoke(tokenA);
                List<DepartmentInfo> departments = new List<DepartmentInfo>();
                DepartmentDAL departmentDAL = new DepartmentDAL();
                foreach (int department_id in department_ids)
                {
                    DepartmentInfo departmentInfo = DepartmentDetailAPI.Invoke(tokenA, department_id);
                    departments.Add(departmentInfo);
                }
                departmentDAL.Add(departments);
                LogMgr.Log("用户数据采集", "1、采集部门 完成");

                LogMgr.Log("用户数据采集", "2、采集用户 开始");
                //2、采集用户
                List<string> userids = UsersAPI.Invoke(tokenB);
                UserDAL userDAL = new UserDAL();

                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        progressBar.Value = 0;
                        progressBar.Minimum = 0;
                        progressBar.Maximum = userids.Count;
                        tlblStatus.Text = "获取用户信息中...";
                        //调用父线程创建的控件
                    }));
                }
                Dictionary<string, string> userID_Name_Dic = new Dictionary<string, string>();
                foreach (string userid in userids)
                {
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            progressBar.Value += 1;
                            tlblStatus.Text = $"已获取 {progressBar.Value} 条用户信息";
                            //调用父线程创建的控件
                        }));
                    }
                    UserInfo userInfo = API.UserDetail90196.UserDetailAPI.Invoke(tokenA, userid);
                    userDAL.Add(userInfo);
                    if (!userID_Name_Dic.ContainsKey(userid))
                        userID_Name_Dic.Add(userid, userInfo.Name);
                }
                LogMgr.Log("用户数据采集", "2、采集用户 完成");

                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        lblStatus.Text = "";
                    }));
                }

                //3、采集用户和部门关系  
                LogMgr.Log("用户数据采集", "3、采集用户和部门关系 开始");
                Dictionary<string, List<int>> dic = UsersAPI.GetUserDeparmentsDic(tokenB);
                UsersDepartmentsRDAL usersDepartmentsRDAL = new UsersDepartmentsRDAL();
                usersDepartmentsRDAL.Add(dic);

                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        progressBar.Value = 0;
                        progressBar.Minimum = 0;
                        progressBar.Maximum = userids.Count;
                    }));
                }
                LogMgr.Log("用户数据采集", "3、采集用户和部门关系 完成");

                //4、采集用户和其客户对应关系
                LogMgr.Log("用户数据采集", "4、采集用户和其客户对应关系 开始");
                List<RelationshipInfo> relationshipInfos = new List<RelationshipInfo>();

                //20240531新增 按仅采集已选定的用户
                userids = userDAL.GetUserIdsRequired();
                foreach (string userid in userids)
                {
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            progressBar.Value += 1;
                            tlblStatus.Text = $"获取 用户-客户 对应关系 {progressBar.Value} ";
                        }));
                    }
                    List<string> exuserids = ExternalUseridsAPI.Invoke(tokenA, userid);
                    foreach (string exuserid in exuserids)
                    {
                        relationshipInfos.Add(new RelationshipInfo(userid, exuserid));
                    }
                }
                UsersCustomersRDAL relationshipDAL = new UsersCustomersRDAL();
                relationshipDAL.Add(relationshipInfos);
                LogMgr.Log("用户数据采集", "4、采集用户和其客户对应关系 完成");

                //5、采集客户详细信息
                LogMgr.Log("用户数据采集", "5、采集客户详细信息 开始");
                CustomerDAL customerDAL = new CustomerDAL();

                Dictionary<string, CustomerInfo> exuserID2CustomerDic = new Dictionary<string, CustomerInfo>();
                exuserID2CustomerDic.Clear();
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        tlblStatus.Text = "";
                        progressBar.Value = 0;
                        progressBar.Minimum = 0;
                        progressBar.Maximum = userids.Count;
                        tlblStatus.Text = "采集客户详细中...";
                    }));
                }
                for (int i = 0; i < userids.Count; i++)
                {
                    string userid = userids[i];
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            tlblStatus.Text = $"采集客户详细中...{i + 1}";
                            progressBar.Value += 1;
                        }));
                    }
                    tokenA = TokenA.GetAccessToken();
                    CustomerDetailBArgs args = new CustomerDetailBArgs();
                    args.userid_list = new string[] { userid };
                    args.limit = 100;
                    args.cursor = "";
                    List<CustomerInfo> customerInfos = CustomerDetailBAPI.Invoke(tokenA, args);

                    foreach (CustomerInfo customerInfo in customerInfos)
                    {
                        string key = customerInfo.Exuserid;
                        if (userID_Name_Dic.ContainsKey(customerInfo.F_UserID))
                            customerInfo.F_UserName = userID_Name_Dic[customerInfo.F_UserID];

                        if (!exuserID2CustomerDic.ContainsKey(key))
                            exuserID2CustomerDic[key] = customerInfo;
                    }
                }
                customerDAL.Add(exuserID2CustomerDic.Values);
                LogMgr.Log("用户数据采集", "5、采集客户详细信息 完成");

                if (obj != null)
                {
                    LogMgr.Log("用户数据采集", "6、采集群组信息 开始");
                    groupsService(); //采集所有群
                    LogMgr.Log("用户数据采集", "6、采集群组信息 完成");
                }

                int total_seconds = (int)Math.Round(stopwatch.Elapsed.TotalSeconds);
                int total_minutes = (int)Math.Round(stopwatch.Elapsed.TotalMinutes);

                //新增20240601
                //从匹配文件中获取是否要一叶匹配
                AppConfigInfo appConfig = AppCofingMgr.Get();
                if (appConfig.YiYeMatched)
                    YiYeSyncMgr.Execute();

                LogMgr.Log("用户数据采集", $"数据采集完成，用时 {total_seconds} 秒，约 {total_minutes} 分钟");

                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        tlblStatus.Text = "采集完成";
                    }));
                }

                if (obj == null)
                    MessageBox.Show("数据采集完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                LogMgr.Log(ex);
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        foreach (var toolStripItem in toolStrip.Items)
                        {
                            ToolStripButton btn = toolStripItem as ToolStripButton;
                            if (btn != null) btn.Enabled = true;
                        }
                        tlblStatus.Text = "";
                    }));
                }
            }
        }
        private void groupsService()
        {
            GroupDAL groupDAL = new GroupDAL();
            string tokenA = TokenA.GetAccessToken(true);
            GroupChatListArgs args = new GroupChatListArgs();

            //获取客户群列表
            List<string> groupIds = GroupChatListAPI.Invoke(tokenA, args);
            List<CustomerGroupInfo> customerGroupInfos = new List<CustomerGroupInfo>();

            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    lblStatus.Text = "采集群组信息中";
                    progressBar.Value = 0;
                    progressBar.Minimum = 0;
                    progressBar.Maximum = groupIds.Count;
                }));
            }

            //获取客户群详情
            foreach (string groupId in groupIds)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        progressBar.Value += 1;
                    }));
                }
                string groupName = "";
                GroupChatDetailArgs agrs = new GroupChatDetailArgs() { chat_id = groupId };
                List<CustomerGroupInfo> memberInfos_temp =
                    GroupChatDetailAPI.InvokePlus(tokenA, agrs, ref groupName);

                groupDAL.Append(new GroupInfo() { ChatID = groupId, Name = groupName });
                customerGroupInfos.AddRange(memberInfos_temp);
            }

            DateTime lastUpdate = DateTime.Now;
            CustomersGroupsDAL customersGroupsDAL = new CustomersGroupsDAL();

            foreach (CustomerGroupInfo customerGroupInfo in customerGroupInfos)
            {
                customerGroupInfo.LastUpdate = lastUpdate;
                customersGroupsDAL.Add(customerGroupInfo);
            }
            customersGroupsDAL.UpdateInGroupStatus(lastUpdate);

            CustomerDAL customerDAL = new CustomerDAL();
            HashSet<string> inGroupUserIds = customersGroupsDAL.GetMemberInGroupHashSet();
            foreach (string exuserid in inGroupUserIds)
            {
                customerDAL.UpdateQWGroupStatus(exuserid, 2);
            }
            HashSet<string> notInGroupUserIds = customersGroupsDAL.GetMemberInGroupHashSet(0);
            foreach (string exuserid in notInGroupUserIds)
            {
                customerDAL.UpdateQWGroupStatus(exuserid, 1);
            }
            new UpdateLogsDAL().Log("企微群", "数据采集");
        }

        private string _cookies;
        private void btnGetCookies_Click(object sender, EventArgs e)
        {
            getCookies();
        }

        private void getCookies()
        {
            _cookies = "";
            //注册获取cookie回调事件
            ICookieManager cookieManager = _chromeBrowser.GetCookieManager();
            CookieVisitor visitor = new CookieVisitor();
            visitor.SendCookie += visitor_SendCookie;
            cookieManager.VisitAllCookies(visitor);
        }

        /// 回调事件
        private void visitor_SendCookie(CefSharp.Cookie obj)
        {
            //_cookies += obj.Domain.TrimStart('.') + "^" + obj.Name + "^" + obj.Value + "\r\n";
            _cookies += obj.Name + "=" + obj.Value + ";";
        }

        private void getBlockedUsersService()
        {
            try
            {
                foreach (var toolStripItem in toolStrip.Items)
                {
                    ToolStripButton btn = toolStripItem as ToolStripButton;
                    if (btn != null) btn.Enabled = false;
                }

                tlblStatus.Text = "获取Cookie倒计时";
                getCookies();
                for (int i = 5; i > 0; i--)
                {
                    tlblStatus.Text = $"获取Cookie倒计时...{i}秒";
                    Thread.Sleep(1000);
                }

                if (!_cookies.Contains("wwrtx.logined=true") ||
                    !_cookies.Contains("wxpay.corpid=") ||
                    !_cookies.Contains("wwrtx.vid="))
                {
                    MessageBox.Show("请先扫码登录后再试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                //这样搞的话，如果有的黑名单用户，没有头像链接，或是头像链接是相同的如保处理
                UserDAL userDAL = new UserDAL();
                List<BlockedInfo> blockedUsers = BlockedUsersCustomAPI.Invoke(_cookies, tlblStatus);

                //清空数据表，一次性导入
                BlockedDAL blockedUserDAL = new BlockedDAL();
                blockedUserDAL.Add(blockedUsers);

                //string json = JsonConvert.SerializeObject(blockedUsers);
                //string fn = Path.Combine(Application.StartupPath, "blockedusers.txt");
                //File.WriteAllText(fn, json, Encoding.UTF8);

                MessageBox.Show($"共采集到黑名单 {blockedUsers.Count} 条记录", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                Logs.LogMgr.Log(ex);
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                foreach (var toolStripItem in toolStrip.Items)
                {
                    ToolStripButton btn = toolStripItem as ToolStripButton;
                    if (btn != null) btn.Enabled = true;
                }
            }
        }



        private void btnGetBlockedUsers_Click(object sender, EventArgs e)
        {
            string html = getHtmlSource();
            if (html.Contains("企业微信扫码登录") && html.Contains("同时支持微信扫码登录"))
            {
                MessageBox.Show("请先扫码登录后再试", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            _thread = new Thread(new ThreadStart(getBlockedUsersService));
            _thread.Start();
        }

        private void btnViewBlockedUsers_Click(object sender, EventArgs e)
        {
            FrmBlockedUsers frm = new FrmBlockedUsers();
            frm.ShowDialog();
        }


        private void btnGetCustomers_Click(object sender, EventArgs e)
        {
            AppConfigInfo appConfigInfo = AppCofingMgr.Get();
            if (
                string.IsNullOrEmpty(appConfigInfo.Corpid) ||
                string.IsNullOrEmpty(appConfigInfo.CorpsecretA) ||
                string.IsNullOrEmpty(appConfigInfo.CorpsecretB)
                )
            {
                MessageBox.Show("请先设置API参数", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            _thread = new Thread(new ParameterizedThreadStart(workService));
            _thread.IsBackground = true;
            _thread.Start(null);
        }

        private void btnClearData_Click(object sender, EventArgs e)
        {
            try
            {
                DialogResult result = MessageBox.Show("确定要清空整个数据库数据？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result != DialogResult.Yes) return;
                foreach (var toolStripItem in toolStrip.Items)
                {
                    ToolStripButton btn = toolStripItem as ToolStripButton;
                    if (btn != null) btn.Enabled = false;
                }
                new SqlDAL().ClearDataBase();
                MessageBox.Show("清空数据成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                LogMgr.Log(ex);
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                foreach (var toolStripItem in toolStrip.Items)
                {
                    ToolStripButton btn = toolStripItem as ToolStripButton;
                    if (btn != null) btn.Enabled = true;
                }
            }
        }

        private void btnOpenLoginPage_Click(object sender, EventArgs e)
        {
            _chromeBrowser.Load("https://work.weixin.qq.com/wework_admin/loginpage_wx");
        }

        private void menuAppSetting_Click(object sender, EventArgs e)
        {
            FrmSetting frm = new FrmSetting();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                AppConfigInfo appConfigInfo = AppCofingMgr.Get();
                if (!string.IsNullOrEmpty(appConfigInfo.CorpName))
                    this.Text = appConfigInfo.CorpName + "---用户信息管理";
                else
                    this.Text = "用户信息管理";
            }
        }


        private void btnSearch_Click(object sender, EventArgs e)
        {
            FrmSearch frm = new FrmSearch();
            frm.ShowDialog();
        }

        private void btnGroups_Click(object sender, EventArgs e)
        {
            FrmGroup frm = new FrmGroup();
            frm.ShowDialog();
        }

        private void menuManage_Tags_Click(object sender, EventArgs e)
        {
            FrmTags frm = new FrmTags();
            frm.ShowDialog();
        }

        private void menuAppTimer_Click(object sender, EventArgs e)
        {
            FrmTimerSetting frm = new FrmTimerSetting();
            frm.ShowDialog();
        }

        private void menuManage_Data_Click(object sender, EventArgs e)
        {
            FrmData frm = new FrmData();
            frm.ShowDialog();
        }

        private void menuSynchoronousMySql_Click(object sender, EventArgs e)
        {
            FrmSynchoronousMySql frm = new FrmSynchoronousMySql();
            frm.ShowDialog();
        }

        private void menuUsersRequiredSetting_Click(object sender, EventArgs e)
        {
            FrmUsersRequired frm = new FrmUsersRequired();
            frm.ShowDialog();
        }

        private void btnTestYiYe_Click(object sender, EventArgs e)
        {
            YiYeSyncMgr.Execute();
        }

        private void menuYiYeSearch_Click(object sender, EventArgs e)
        {
            FrmYiYe frm = new FrmYiYe();
            frm.ShowDialog();
        }
    }
}
